package com.easy.api.factory.api;

import com.easy.api.annotation.ApiMapping;
import com.easy.api.annotation.ApiProxy;
import com.easy.api.bean.api.OpenConfig;
import com.easy.api.http.HttpMethod;
import com.easy.api.factory.api.request.HeaderRequest;
import com.easy.api.utils.ApplicationContextUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author liuyuan
 * @Date 2020-04-18 13:44
 * @Version 1.0
 */
public class ApiInvocationProxy implements InvocationHandler {

    private Class<?> interfaceClass;

    public Object bind(Class<?> cls) {
        this.interfaceClass = cls;
        return Proxy.newProxyInstance(cls.getClassLoader(), new Class[] {interfaceClass}, this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Class<?>[] interfaces = proxy.getClass().getInterfaces();
        ApiProxy apiProxy = null;
        for (Class<?> cls : interfaces) {
            apiProxy = cls.getAnnotation(ApiProxy.class);
            if (apiProxy != null) {
                break;
            }
        }
        ApiMapping apiMapping = getApiMapping(method);
        ApplicationContext applicationContext = ApplicationContextUtils.getApplicationContext();
        //todo 接口参数优先级最高,其次配置
        OpenConfig openConfig = null;
        if(args.length> 1){
            openConfig = (OpenConfig)args[1];
        }
        if(openConfig == null){
            openConfig = applicationContext.getBean(OpenConfig.class);
        }
        HttpMethod httpMethod = HttpMethod.toEnum(apiMapping.method().getCode());
        assert httpMethod != null;

        /**
         * 请求策略
         * */
        HeaderRequest requestService = null;
        try {
            requestService = (HeaderRequest)applicationContext.getBean(httpMethod.getService());
        } catch (BeansException e) {
            e.printStackTrace();
            requestService = (HeaderRequest)applicationContext.getBean(httpMethod.getService(),httpMethod.getaClass());
        }
        requestService.buildHeaderRequest(apiProxy,apiMapping,openConfig,method);
        return requestService.requestStrategy(args[0]);
    }

    private ApiMapping getApiMapping(Method method) {
        return AnnotationUtils.findAnnotation(method, ApiMapping.class);
    }


}
